package com.example.managemyself.api.service;

import com.example.managemyself.api.entity.User;
import com.example.managemyself.api.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 用户服务类
 */
@Service
@Transactional
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    /**
     * 创建新用户
     */
    public User createUser(User user) {
        // 检查用户名是否已存在
        if (userRepository.existsByUsername(user.getUsername())) {
            throw new RuntimeException("用户名已存在: " + user.getUsername());
        }
        
        // 检查邮箱是否已存在
        if (user.getEmail() != null && userRepository.existsByEmail(user.getEmail())) {
            throw new RuntimeException("邮箱已存在: " + user.getEmail());
        }
        
        // 加密密码
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        
        // 设置默认值
        if (user.getRole() == null) {
            user.setRole(User.Role.USER);
        }
        if (user.getStatus() == null) {
            user.setStatus(User.Status.ACTIVE);
        }
        
        return userRepository.save(user);
    }
    
    /**
     * 根据ID获取用户
     */
    public Optional<User> getUserById(Long id) {
        return userRepository.findById(id);
    }
    
    /**
     * 根据用户名获取用户
     */
    public Optional<User> getUserByUsername(String username) {
        return userRepository.findByUsername(username);
    }
    
    /**
     * 根据邮箱获取用户
     */
    public Optional<User> getUserByEmail(String email) {
        return userRepository.findByEmail(email);
    }
    
    /**
     * 根据用户名或邮箱获取用户
     */
    public Optional<User> getUserByUsernameOrEmail(String usernameOrEmail) {
        return userRepository.findByUsernameOrEmail(usernameOrEmail);
    }
    
    /**
     * 更新用户信息
     */
    public User updateUser(Long id, User userDetails) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在: " + id));
        
        // 更新基本信息
        if (userDetails.getFullName() != null) {
            user.setFullName(userDetails.getFullName());
        }
        if (userDetails.getEmail() != null && !userDetails.getEmail().equals(user.getEmail())) {
            if (userRepository.existsByEmail(userDetails.getEmail())) {
                throw new RuntimeException("邮箱已存在: " + userDetails.getEmail());
            }
            user.setEmail(userDetails.getEmail());
        }
        if (userDetails.getPhone() != null) {
            user.setPhone(userDetails.getPhone());
        }
        if (userDetails.getAvatarUrl() != null) {
            user.setAvatarUrl(userDetails.getAvatarUrl());
        }
        
        return userRepository.save(user);
    }
    
    /**
     * 更新用户密码
     */
    public void updatePassword(Long id, String oldPassword, String newPassword) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在: " + id));
        
        // 验证旧密码
        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new RuntimeException("旧密码不正确");
        }
        
        // 更新密码
        user.setPassword(passwordEncoder.encode(newPassword));
        userRepository.save(user);
    }
    
    /**
     * 重置用户密码
     */
    public void resetPassword(Long id, String newPassword) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在: " + id));
        
        user.setPassword(passwordEncoder.encode(newPassword));
        userRepository.save(user);
    }
    
    /**
     * 更新用户状态
     */
    public void updateUserStatus(Long id, User.Status status) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在: " + id));
        
        user.setStatus(status);
        userRepository.save(user);
    }
    
    /**
     * 更新用户角色
     */
    public void updateUserRole(Long id, User.Role role) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在: " + id));
        
        user.setRole(role);
        userRepository.save(user);
    }
    
    /**
     * 记录用户登录时间
     */
    public void recordLoginTime(Long id) {
        userRepository.updateLastLoginTime(id, LocalDateTime.now());
    }
    
    /**
     * 删除用户
     */
    public void deleteUser(Long id) {
        if (!userRepository.existsById(id)) {
            throw new RuntimeException("用户不存在: " + id);
        }
        userRepository.deleteById(id);
    }
    
    /**
     * 获取所有用户
     */
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
    
    /**
     * 分页获取用户
     */
    public Page<User> getUsers(Pageable pageable) {
        return userRepository.findAll(pageable);
    }
    
    /**
     * 根据状态获取用户
     */
    public List<User> getUsersByStatus(User.Status status) {
        return userRepository.findByStatus(status);
    }
    
    /**
     * 根据角色获取用户
     */
    public List<User> getUsersByRole(User.Role role) {
        return userRepository.findByRole(role);
    }
    
    /**
     * 搜索用户
     */
    public Page<User> searchUsers(String keyword, Pageable pageable) {
        return userRepository.searchUsers(keyword, pageable);
    }
    
    /**
     * 获取最近活跃的用户
     */
    public List<User> getRecentlyActiveUsers(LocalDateTime since) {
        return userRepository.findRecentlyActiveUsers(since);
    }
    
    /**
     * 验证用户密码
     */
    public boolean validatePassword(String username, String password) {
        Optional<User> userOpt = userRepository.findByUsername(username);
        if (userOpt.isPresent()) {
            User user = userOpt.get();
            return passwordEncoder.matches(password, user.getPassword());
        }
        return false;
    }
    
    /**
     * 检查用户名是否可用
     */
    public boolean isUsernameAvailable(String username) {
        return !userRepository.existsByUsername(username);
    }
    
    /**
     * 检查邮箱是否可用
     */
    public boolean isEmailAvailable(String email) {
        return !userRepository.existsByEmail(email);
    }
    
    /**
     * 获取用户统计信息
     */
    public UserStats getUserStats() {
        List<Object[]> roleStats = userRepository.countUsersByRole();
        List<Object[]> statusStats = userRepository.countUsersByStatus();
        
        UserStats stats = new UserStats();
        stats.setTotalUsers(userRepository.count());
        
        for (Object[] row : roleStats) {
            User.Role role = (User.Role) row[0];
            Long count = (Long) row[1];
            if (role == User.Role.ADMIN) {
                stats.setAdminCount(count);
            } else if (role == User.Role.USER) {
                stats.setUserCount(count);
            }
        }
        
        for (Object[] row : statusStats) {
            User.Status status = (User.Status) row[0];
            Long count = (Long) row[1];
            if (status == User.Status.ACTIVE) {
                stats.setActiveCount(count);
            } else if (status == User.Status.INACTIVE) {
                stats.setInactiveCount(count);
            } else if (status == User.Status.LOCKED) {
                stats.setLockedCount(count);
            }
        }
        
        return stats;
    }
    
    /**
     * 用户统计信息类
     */
    public static class UserStats {
        private Long totalUsers = 0L;
        private Long adminCount = 0L;
        private Long userCount = 0L;
        private Long activeCount = 0L;
        private Long inactiveCount = 0L;
        private Long lockedCount = 0L;
        
        // Getters and Setters
        public Long getTotalUsers() { return totalUsers; }
        public void setTotalUsers(Long totalUsers) { this.totalUsers = totalUsers; }
        
        public Long getAdminCount() { return adminCount; }
        public void setAdminCount(Long adminCount) { this.adminCount = adminCount; }
        
        public Long getUserCount() { return userCount; }
        public void setUserCount(Long userCount) { this.userCount = userCount; }
        
        public Long getActiveCount() { return activeCount; }
        public void setActiveCount(Long activeCount) { this.activeCount = activeCount; }
        
        public Long getInactiveCount() { return inactiveCount; }
        public void setInactiveCount(Long inactiveCount) { this.inactiveCount = inactiveCount; }
        
        public Long getLockedCount() { return lockedCount; }
        public void setLockedCount(Long lockedCount) { this.lockedCount = lockedCount; }
    }
} 